home *** CD-ROM | disk | FTP | other *** search
/ Programming Sound Cards / Programming Sound Cards.iso / sound_09 / adlplay.bas next >
BASIC Source File  |  1995-01-01  |  8KB  |  242 lines

  1. ' **********************************************************************
  2. ' ** Program:         ADLPLAY.BAS                                     **
  3. ' ** Type   :         Main Program                                    **
  4. ' ** Author :         Joseph Scally                                   **
  5. ' ** Date   :         June 89                                         **
  6. ' ** Purpose:         Play ADLIB MUSIC CARD .ROL FILES AND DISPLAY    **
  7. ' **                  STATISTICS.                                     **
  8. ' **********************************************************************
  9.  
  10. REM $INCLUDE: 'Mstruct.h'
  11. REM $INCLUDE: 'Sound.h'
  12.  DEFINT A-Z
  13.  DIM SHARED INSTRUM(MAXPARAMETERS)          'Holds Instrument Parameters
  14.  DIM SHARED DirEntry$(255, 4)               'Directory Info For Display
  15.  DIM Items$(55)                             'Retains Instruments used for
  16.                           'Display Purposes
  17.  
  18. OpenScreen
  19.  
  20. top:
  21.  Iptr% = 0
  22.  IECount = 0
  23.  Path$ = "c:\music\*.rol"
  24.  GetDirData Path$, DirEntry$(), 64, EntryCount%
  25.  ShowDir 5, 4, 0, 0, 6, 1, 0, 17, DirEntry$(), Reply%, "N"
  26.  Path$ = "c:\music\"
  27.  Initialize
  28.  SetMode PERCUSSIVE
  29.  ROLFile = FREEFILE
  30.  OPEN Path$ + DirEntry$(Reply%, 0) FOR BINARY AS ROLFile
  31.  GET ROLFile, 1, Mh
  32.  Tempo Mh.Tempo
  33. '=================== Set Tempo Events ==================
  34.  FOR TE = 1 TO Mh.TEvents
  35.      GET ROLFile, , TempoEvent
  36.      Soundcard fSDSetTempo, (Mh.Tempo * TempoEvent.Tmultiplier), TempoEvent.TimeEvent, Mh.TicksPerBeat, NULL, NULL
  37.  NEXT TE
  38. '========================================================
  39.  
  40.  FOR voice% = 0 TO MAXVOICES
  41.      GET ROLFile, , VoiceHeader
  42.      SetVoice voice%
  43.      VHD = VoiceHeader.Vduration
  44.      DO WHILE VHD > 0
  45.       GET ROLFile, , Pnote
  46.       LDuration = Pnote.Duration
  47.       Dduration = Pnote.Duration
  48.       IF Pnote.Note = NULL THEN
  49.          Dduration = NULL
  50.       END IF
  51.       Pnote.Note = Pnote.Note - NOTEOFFSET
  52.       PlayNote Pnote.Note, Dduration, Mh.TicksPerBeat, LDuration, Mh.TicksPerBeat
  53.       VHD = VHD - Pnote.Duration
  54.      LOOP
  55. '=========== Set Instrument Events =====================================
  56.      GET ROLFile, , Af             'This Af stuff is necessary because
  57.                     'I have to dump 15 unused bytes every
  58.                     'So often.
  59.  
  60.      GET ROLFile, , NuminstruEvents
  61.      FOR II = 1 TO NuminstruEvents.NumEvents
  62.       GET ROLFile, , InstrumentEvent
  63.       Setinstrument INSTRUM%(), InstrumentEvent.InstrumentName, InstrumentEvent.TimeInTicks, Mh.TicksPerBeat, Iptr%
  64.       Iptr% = Iptr% + PARAMETERS
  65.       ' **** Save instrument names for later display *****
  66.       Newins$ = UCASE$(StripCString$(InstrumentEvent.InstrumentName))
  67.       Items$(IECount) = STR$(voice%) + SPACE$(8 - (LEN(STR$(voice%)))) + Newins$ + SPACE$(10 - LEN(Newins$)) + STR$(InstrumentEvent.TimeInTicks)
  68.       IECount = IECount + 1
  69.      NEXT
  70. '========================================================================
  71.  
  72. '========== Set Volume Events ===========================================
  73.      GET ROLFile, , Af
  74.      GET ROLFile, , NumVolEvents
  75.      FOR VI = 1 TO NumVolEvents.NumEvents
  76.       GET ROLFile, , VolumeEvent
  77.       Soundcard 8, (255 * VolumeEvent.VolMultiplier), 255, VolumeEvent.TimeEvent, Mh.TicksPerBeat, 0
  78.      NEXT
  79. '==========================================================================
  80.  
  81. '========== Set Pitch Events ===============================================
  82.      GET ROLFile, , Af
  83.      GET ROLFile, , NumPitchEvents
  84.      FOR Pitch = 1 TO NumPitchEvents.NumEvents
  85.       GET ROLFile, , PitchEvent
  86.       Soundcard FSDSETPITCH, 0, (PitchEvent.VolMultiplier * 100), 98, PitchEvent.TimeEvent, Mh.TicksPerBeat
  87.      NEXT
  88. '============================================================================
  89.  NEXT voice%
  90.  CLOSE ROLFile
  91.  COLOR 0, 6
  92. '============================================================================
  93. 'Put Some Stats on the Screen...More to come later
  94.  LOCATE 6, 28
  95.  PRINT "Basic Tempo     "; Mh.Tempo
  96.  LOCATE , 28
  97.  PRINT "Time Events     "; Mh.TEvents
  98.  LOCATE , 28
  99.  PRINT "Pitch Events    "; NumPitchEvents.NumEvents
  100.  LOCATE , 28
  101.  PRINT "Volume Events   "; NumVolEvents.NumEvents
  102.  LOCATE , 28
  103.  PRINT "Instrum Events  "; IECount%
  104.  LOCATE , 28
  105.  PRINT "Ticks per Beat  "; Mh.TicksPerBeat
  106.  LOCATE 6, 55
  107.  FOR Sins = 0 TO 16
  108.  LOCATE , 55
  109.  PRINT Items$(Sins)
  110.  NEXT
  111.  StartSong
  112.  
  113.  'Low Level Call to Sound Driver. When AX = 0
  114.  'The song is over.
  115.  
  116.  OutRegs.ax = 1                    'Force it to make one loop
  117.  DO WHILE OutRegs.ax               'While AX <> 0
  118.  InRegs.si = fSDGetState           'Call Function fSDGetState = 4
  119.                     'Function in SI
  120.  INTERRUPT &H65, InRegs, OutRegs   'Int 65H = Sound Driver.
  121.  LOOP
  122. GOTO top
  123.  
  124. DEFSNG A-Z
  125. SUB Initialize
  126. ' ******************************************************************
  127. ' ** This Routine Performs 3 functions. It Call function 0 to     **
  128. ' ** Initialize The Driver, Starts The Relative Time Clock and    **
  129. ' ** Sets the mode to Percussive which is used most of the time   **
  130. ' ** Throughout these routines you will see "NULL" I defined this **
  131. ' ** to show where the value sent to the interface is meaningless **
  132. ' ******************************************************************
  133.  
  134.  Soundcard FSDINIT, NULL, NULL, NULL, NULL, NULL
  135.  StartTime
  136.  SetMode PERCUSSIVE
  137. END SUB
  138.  
  139. DEFINT A-Z
  140. 'Set up the opening screen
  141. SUB OpenScreen STATIC
  142.  CLS
  143.  SetBack 176, 6                   ' ***** Library Routine
  144.  COLOR 14, 6
  145.  LOCATE 1, 1
  146.  PRINT SPACE$(80);
  147.  LOCATE 2, 1
  148.  PRINT "      AdLib Player / Analyzer     Ver 1.0          J. Scally        June 89     "
  149.  Makbox 5, 52, 0, 6, 25, 17, 0    ' ***** Library Routine
  150.  Makbox 5, 24, 0, 6, 26, 17, 0
  151.  LOCATE 5, 53
  152.  PRINT "[Voice#]-[Instrum]-[Tick]"
  153.  LOCATE 5, 32
  154.  PRINT "[Statistics]"
  155.  
  156. END SUB
  157.  
  158. DEFSNG A-Z
  159. SUB PlayNote (Note%, Duration%, Dlay%, AfterH%, AfterL%)
  160.  s0% = FSDPLAYNOTEDEL
  161.  Soundcard s0%, Note%, Duration%, Dlay%, AfterH%, AfterL%
  162. END SUB
  163.  
  164. DEFINT A-Z
  165. ' *****************************************************************
  166. ' ** This Routine Fills The screen Instantly With Char% in Color **
  167. ' ** Attr%.                                                      **
  168. ' *****************************************************************
  169. SUB SetBack (Char%, Attr%)
  170. Routine$ = "Setback"
  171.  CLS
  172.  InRegs.ax = &H900 + Char%
  173.  InRegs.bx = Attr%
  174.  InRegs.cx = &H7D0
  175.  INTERRUPT &H10, InRegs, OutRegs
  176. END SUB
  177.  
  178. '*******************************************************************
  179. '** This Routine Passes a Far Pointer to instrument parameters.   **
  180. '** Since This can also represent a change of instruments at      **
  181. '** a future time as specified in num/den, the array must remain  **
  182. '** valid. Since you can't dim on the fly, or if someone knows of **
  183. '** a technique to do it I would love to here it, I used a single **
  184. '** table to hold all of the parameters. Believe me it's not as   **
  185. '** bad as it sounds.                                             **
  186. '*******************************************************************
  187. '
  188. SUB Setinstrument (ARRAY(), InsName$, num, den, ptr)
  189.  
  190.  InsFile = FREEFILE
  191.  FileName$ = "c:\music\ins\" + StripCString$(InsName$) + ".ins"
  192.  OPEN FileName$ FOR BINARY AS InsFile
  193.  FOR i = 1 TO PARAMETERS
  194.      GET InsFile, , ARRAY(i + ptr)
  195.  NEXT i
  196.  CLOSE InsFile
  197.  Soundcard FSDSETTIMBRE, VARPTR(ARRAY(2 + ptr)), VARSEG(ARRAY(2 + ptr)), num, den, NULL
  198.  'Note in .Ins Files the first 2 bytes are not paramaters hence 2+ Ptr
  199. END SUB
  200.  
  201. SUB SetMode (Mode%)
  202.  'Set Mode to PERCUSSIVE or MELODIC
  203.  Soundcard FSDSETMODE, Mode, NULL, NULL, NULL, NULL
  204. END SUB
  205.  
  206. DEFSNG A-Z
  207. SUB SetVoice (voice%)
  208.  'SET active Voice  ( 0 - 11 )
  209.  Soundcard FSDSETACTVOICE, voice%, NULL, NULL, NULL, NULL
  210. END SUB
  211.  
  212. SUB StartSong
  213.  'Start Playing
  214.  Soundcard FSDSETSTATE, CARDON, NULL, NULL, NULL, NULL
  215. END SUB
  216.  
  217. SUB StartTime
  218.  'Called By Initialize and explained there
  219.  Soundcard FSDRELTIMESTART, 0, 1, NULL, NULL, NULL
  220. END SUB
  221.  
  222. DEFINT A-Z
  223. 'This function is necessary because the File Names in the .Ins files
  224. 'are C or Zero Terminated strings making it impossible to do an
  225. 'RTRIM$ to tidy up
  226. '
  227. FUNCTION StripCString$ (CString$)
  228.  FOR l = 1 TO LEN(CString$)
  229.      ch$ = MID$(CString$, l, 1)
  230.      IF ch$ = CHR$(0) THEN EXIT FOR
  231.      n$ = n$ + ch$          'Build New String until NULL encountered
  232.  NEXT
  233.      StripCString$ = n$
  234. END FUNCTION
  235.  
  236. DEFSNG A-Z
  237. SUB Tempo (beats)
  238. 'Set Tempo to Beats per
  239.  Soundcard fSDSetTempo, beats, 0, 1, 0, 0
  240. END SUB
  241.  
  242.